home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
oasis
/
oasis1-1.lha
/
oasis-1.1
/
kern.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-01
|
29KB
|
974 lines
/*==========================================================================*
Oasis Alpha Version 1.1 (C) Copyright 1992 Fah-Chun Cheong
Revised: 5/1/92 by: fcc@eecs.umich.edu and The University of Michigan
------------------------------------------------------------------------
Permission to use, copy, modify, distribute, sell and resell Oasis Alpha
software and its documentation for any purpose and without fee is hereby
granted, provided that the authorship be appropriately credited and
acknowledged, and that the above copyright notice appear in all copies
and both the copyright notice and this permission notice appear in
supporting documentation. The author makes no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty. Oasis Alpha is free, caveat emptor!
------------------------------------------------------------------------
To request Oasis Alpha source code: oasis-alpha-request@eecs.umich.edu
To enroll in the mailing list: oasis-alpha-request@eecs.umich.edu
To send bug reports: oasis-alpha-bugs@eecs.umich.edu
To discuss openly all matters Oasis: oasis-alpha@eecs.umich.edu
*==========================================================================*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <fcntl.h>
#ifdef _AIX
#include <sys/select.h>
#endif _AIX
#include "system.h"
#ifdef SPARC
#define TWO 2
#else
#define TWO 0
#endif SPARC
#ifndef KERN_BUG
#define tracer(s,sz,buf)
#define print1(s,a)
#else
#define print1(s,a) printf(s, a)
#endif KERN_BUG
#define TNO 64
#define STACKSZ (1024 * 100)
#define HEAPSZ (1024 * 1000)
#define BREAKSZ (1024 * 800)
#define MESGSZ (1024 * 200)
#define new(arg) (*(u_long *) arg & 0x0003)
#define link(arg,qtr,q) (*qtr = *(u_long *) arg,\
*(u_long *) arg = (u_long) qtr,\
*--q = arg,\
qtr += szof(qtr))
#define move(arg,qtr,q) (new(arg) ? link(arg, qtr, q) : NUL)
#define copy(arg,qtr,q) (arg ? (move(arg, qtr, q), *(u_long *) arg) : NUL)
#define swizzle(arg,ho) (arg ? arg + ho : NUL)
#define max(m,n) (m > n ? m : n)
extern u_long cno;
extern long *ctab[];
extern u_long **dtab[];
extern u_long hno;
extern Host htab[];
Space space;
u_long *root;
static u_long *hook[2];
static struct sigvec svec = { on_arrival, 0, SV_ONSTACK };
static struct sigstack sstack = { NUL, 0 };
static int ssock = 3;
static Thread ttab[TNO];
static Thread **qhead;
static Thread **qtail;
static int qno;
static u_long *vmap[] = {
(u_long *) collect,
(u_long *) mcret,
(u_long *) msend,
(u_long *) mdone,
(u_long *) mquit,
(u_long *) mrecv,
(u_long *) cwait,
(u_long *) cpost,
(u_long *) zero,
(u_long *) drem,
(u_long *) iceil,
(u_long *) ifloor,
(u_long *) iround,
(u_long *) itrunca,
(u_long *) ffloat,
(u_long *) sqrt,
(u_long *) sin,
(u_long *) cos,
(u_long *) tan,
(u_long *) asin,
(u_long *) acos,
(u_long *) atan,
(u_long *) sinh,
(u_long *) cosh,
(u_long *) tanh,
(u_long *) asinh,
(u_long *) acosh,
(u_long *) atanh,
(u_long *) log10,
(u_long *) logb,
(u_long *) log,
(u_long *) log1p,
(u_long *) pow,
(u_long *) exp,
(u_long *) expm1,
(u_long *) dbug
};
static struct rusage gc_ru1, gc_ru2;
static long gc_time_u;
static long gc_time_s;
static struct rusage ru1, ru2;
static struct timeval tm1, tm2;
static struct timezone tz;
static long time_u;
static long time_s;
static long time_e;
static int gcno;
static int thno;
static int rpcno;
void init_kern(n)
int n;
{
int i;
qno = n + 2;
qhead = (Thread **) calloc(qno, sizeof(Thread *));
qtail = (Thread **) calloc(qno, sizeof(Thread *));
qhead[0] = &ttab[0];
for (i = 1; i < TNO; i++)
ttab[i-1].next = &ttab[i];
qtail[0] = &ttab[TNO - 1];
space.heap = (u_long *) malloc(HEAPSZ * 4 * 2);
space.next = space.heap + HEAPSZ;
if (space.heap == NULL) {
error0("System out of memory\n");
exit(-1);
}
space.hp = space.heap;
space.bp = space.heap + BREAKSZ;
dtab[0] = vmap;
hook[0] = (u_long *) done;
hook[1] = (u_long *) quit;
signal(SIGQUIT, on_fault);
signal(SIGILL, on_fault);
signal(SIGTRAP, on_fault);
signal(SIGIOT, on_fault);
signal(SIGEMT, on_fault);
signal(SIGBUS, on_fault);
signal(SIGSEGV, on_fault);
signal(SIGSYS, on_fault);
sstack.ss_sp = (char *) malloc(STACKSZ * 4) + STACKSZ*2;
sstack.ss_onstack = 0;
sigstack(&sstack, 0);
sigvec(SIGIO, &svec, 0);
if (fcntl(ssock, F_SETOWN, getpid()) < 0)
perror("F_SETOWN error");
if (fcntl(ssock, F_SETFL, FASYNC) < 0)
perror("F_SETFL FASYNC error");
}
void stat_on()
{
gcno = 0;
thno = 1;
rpcno = 0;
gc_time_u = 0;
gc_time_s = 0;
tz.tz_minuteswest = 0;
tz.tz_dsttime = 0;
gettimeofday(&tm1, &tz);
getrusage(0, &ru1);
}
void stat_off()
{
getrusage(0, &ru2);
gettimeofday(&tm2, &tz);
time_u = (ru2.ru_utime.tv_sec - ru1.ru_utime.tv_sec) * 1000000
+ (ru2.ru_utime.tv_usec - ru1.ru_utime.tv_usec) + 1;
time_s = (ru2.ru_stime.tv_sec - ru1.ru_stime.tv_sec) * 1000000
+ (ru2.ru_stime.tv_usec - ru1.ru_stime.tv_usec) + 1;
time_e = (tm2.tv_sec - tm1.tv_sec) * 1000000
+ (tm2.tv_usec - tm1.tv_usec) + 1;
fprintf(stderr, "%.1fu %.1fs %d:%02d %d%% %d+%dio %dpf+%dw [%.1fu %.1fs %dgc] %dth %drpc\n",
(double) time_u / 1000000.0, (double) time_s / 1000000.0,
time_e / 60000000, time_e / 1000000 % 60,
(int) ((time_u + time_s) * 100.0 / time_e),
ru2.ru_inblock - ru1.ru_inblock, ru2.ru_oublock - ru1.ru_oublock,
ru2.ru_majflt - ru1.ru_majflt, ru2.ru_nswap - ru1.ru_nswap,
(double) gc_time_u / 1000000.0, (double) gc_time_s / 1000000.0,
gcno, thno, rpcno);
}
u_long run(buf, size, start)
char *buf;
int size;
u_long *start;
{
Thread *thread;
int mask;
mask = sigblock(sigmask(SIGIO));
thread = qhead[0];
tmove(0, 1);
thread->stack = (u_long *) malloc(STACKSZ * 4);
thread->mp = thread->stack - 1;
thread->sb = thread->stack + STACKSZ;
thread->sp = thread->sb - 2;
thread->pc = start;
thread->hook = hook;
thread->mbuf = NUL;
thread->sp[1] = (u_long) root;
#if !defined(M68K) && !defined(I386)
thread->sp = thread->sb;
#endif !M68K && !I386
sigsetmask(mask);
stat_on();
space.hp = call(dtab, &space, thread);
stat_off();
if (buf && !*space.hp)
bcopy(thread->sb - atoi(buf) - 2, buf + size, atoi(buf) * sizeof(u_long));
mask = sigblock(sigmask(SIGIO));
free(thread->stack);
tmove(1, 0);
sigsetmask(mask);
return *space.hp;
}
VOID on_fault()
{
int i;
fprintf(stderr, "\n[pid %d] died:\n", getpid());
for (i = 1; i < qno; i++) {
Thread *thread = qhead[i];
if (thread) fprintf(stderr, "[%d]:", i);
for (; thread; thread = thread->next)
fprintf(stderr, "\t0x%08x", thread);
if (qhead[i]) putc('\n', stderr);
}
fprintf(stderr, "\nCore dumped:\n");
fprintf(stderr, "heap = 0x%08x\n", space.heap);
fprintf(stderr, "hp = 0x%08x\n", space.hp);
fprintf(stderr, "bp = 0x%08x\n", space.bp);
fprintf(stderr, "stack = 0x%08x\n", qhead[1]->stack);
fprintf(stderr, "sb = 0x%08x\n", qhead[1]->sb);
fprintf(stderr, "sp = 0x%08x\n", qhead[1]->sp);
fprintf(stderr, "pc = 0x%08x\n", qhead[1]->pc);
fprintf(stderr, "hook = 0x%08x\n", qhead[1]->hook);
fprintf(stderr, "root = 0x%08x\n", root);
for (i = 1; i < 32; i++) {
if (i % 4 == 1) fprintf(stderr, "\n[%08x] ", qhead[1]->sb - i);
fprintf(stderr, "%08x ", qhead[1]->sb[-i]);
}
putc('\n', stderr);
for (i = 0; i < 32; i++) {
if (i % 4 == 0) fprintf(stderr, "\n[%08x] ", space.heap + i);
fprintf(stderr, "%08x ", space.heap[i]);
}
putc('\n', stderr);
exit(0);
}
VOID on_arrival()
{
struct timeval timeout;
fd_set fdset;
Socket client;
int csock;
int sz = sizeof(client);
u_long *buf;
u_long size;
print1("[pid %d] !\n", getpid());
FD_ZERO(&fdset);
FD_SET(ssock, &fdset);
timeout.tv_sec = 0L;
timeout.tv_usec = 0L;
switch (select(ssock + 1, &fdset, (fd_set *) 0, (fd_set *) 0, &timeout)) {
case 1: break;
case 0: return;
default: perror("selecting stream socket");
}
if ((csock = accept(ssock, (Sock *) &client, &sz)) < 0) {
perror("accepting stream connection");
exit(-1);
}
readn(csock, &size, sizeof(u_long));
size = ntohl(size);
buf = (u_long *) malloc(size);
buf[SIZE] = size;
readn(csock, buf + 1, size - sizeof(u_long));
close(csock);
reorder(buf, size);
switch (buf[MTYPE]) {
case MSEND: qhead[0]->mbuf = buf;
tmove(0, 1);
tracer("received request", size, buf); break;
case MDONE: *(u_long *) buf[XID] = (u_long) buf;
tracer("received reply", size, buf); break;
case MQUIT: *(u_long *) buf[XID] = (u_long) buf;
tracer("received failure", size, buf); break;
}
}
void reorder(buf, size)
u_long *buf;
u_long size;
{
if (buf[ENDIAN] != 0xbeeffeed) {
char *ptr = (char *) buf + 4;
for (; ptr < (char *) buf + size; ptr += 4) {
char c0 = ptr[0];
char c1 = ptr[1];
ptr[0] = ptr[3];
ptr[3] = c0;
ptr[1] = ptr[2];
ptr[2] = c1;
}
}
}
u_long create(addr, port, port0, buf, size)
u_long addr;
u_long port;
u_long port0;
u_long *buf;
u_long size;
{
Socket server;
int csock;
#ifdef MESG_BUG
int i;
for (i = 0; i < size / 4; i++)
printf("[%04d] 0x%08x (%d)\n", i, buf[i], buf[i]);
#endif MESG_BUG
if ((csock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("opening stream socket");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(addr);
server.sin_port = htons((u_short) port);
if (connect(csock, (Sock *) &server, sizeof(server)))
perror("connecting stream socket");
else {
port0 = htonl(port0);
writn(csock, &port0, sizeof(u_long));
writn(csock, buf, size);
readn(csock, &port0, sizeof(u_long));
close(csock);
port0 = ntohl(port0);
}
return port0;
}
void transmit(addr, port, buf, size)
u_long addr;
u_long port;
u_long *buf;
u_long size;
{
Socket server;
int csock;
#ifdef MESG_BUG
int i;
for (i = 0; i < size / 4; i++)
printf("[%04d] 0x%08x (%d)\n", i, buf[i], buf[i]);
#endif MESG_BUG
if ((csock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("opening stream socket");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(addr);
server.sin_port = htons((u_short) port);
if (connect(csock, (Sock *) &server, sizeof(server)))
perror("connecting stream socket");
else writn(csock, buf, size);
close(csock);
}
Space *collect(sp, pc)
u_long *sp;
u_long *pc;
{
u_long *ptr = space.next;
u_long *qtr = ptr;
u_long *p = ptr + HEAPSZ;
u_long *q = ptr + HEAPSZ;
Thread *tp;
int mask;
int i;
getrusage(0, &gc_ru1);
#ifdef KERN_BUG
printf("Garbage collecting... ");
fflush(stdout);
#endif KERN_BUG
mask = sigblock(sigmask(SIGIO));
qhead[1]->sp = sp;
qhead[1]->pc = pc;
for (i = 1; i < qno; i++)
if (tp = qhead[i])
do if (!tp->mbuf)
qtr = trace(tp, qtr, &q);
while (tp = tp->next);
space.hp = traverse(ptr, qtr, p, &q);
space.bp = ptr + BREAKSZ;
root = (u_long *) root[0];
space.next = space.heap;
space.heap = ptr;
sigsetmask(mask);
#ifdef KERN_BUG
printf("%d bytes (%d%%) used, %d bytes (%d%%) free.\n",
(space.hp - space.heap) * 4, (space.hp - space.heap) * 100 / BREAKSZ,
(space.bp - space.hp) * 4, (space.bp - space.hp) * 100 / BREAKSZ);
#endif KERN_BUG
getrusage(0, &gc_ru2);
gc_time_u += (gc_ru2.ru_utime.tv_sec - gc_ru1.ru_utime.tv_sec) * 1000000
+ (gc_ru2.ru_utime.tv_usec - gc_ru1.ru_utime.tv_usec) + 1;
gc_time_s += (gc_ru2.ru_stime.tv_sec - gc_ru1.ru_stime.tv_sec) * 1000000
+ (gc_ru2.ru_stime.tv_usec - gc_ru1.ru_stime.tv_usec) + 1;
gcno++;
return &space;
}
u_long *trace(tp, qtr, qp)
Thread *tp;
u_long *qtr;
u_long**qp;
{
u_long *sb = tp->sb;
u_long *sp = tp->sp;
u_long *pc = tp->pc - 2 - TWO;
u_long *q = *qp;
if (tp != qhead[1])
pc -= pc[-1];
while (sp < sb) {
long *cp = (long *) pc + 2 + TWO;
u_long *gp;
for (; *cp >= 0; cp++)
sp[*cp] = copy(sp[*cp], qtr, q);
pc = (u_long *) sp[-*cp - 1];
gp = (u_long *) sp[-*cp];
sp[-*cp++] = copy((u_long) gp, qtr, q);
for (; *cp >= 0; cp += 2)
if (gp[cp[1]] == T_POINTER)
sp[*cp] = copy(sp[*cp], qtr, q);
sp += -*cp;
}
*qp = q;
return qtr;
}
u_long *traverse(ptr, qtr, p, qp)
u_long *ptr;
u_long *qtr;
u_long *p;
u_long**qp;
{
u_long *q = *qp;
while (ptr < qtr) {
u_long *hp = (u_long *) *--p;
switch (idof(*hp)) {
case I_HANDLE: ptr[1] = hp[1];
ptr[2] = hp[2];
ptr[3] = hp[3];
ptr += 4; break;
case I_LISTC:
case I_LISTI:
case I_LISTF: ptr[1] = hp[1];
ptr[2] = copy(hp[2], qtr, q);
ptr += 3; break;
case I_LISTP: ptr[1] = copy(hp[1], qtr, q);
ptr[2] = copy(hp[2], qtr, q);
ptr += 3; break;
case I_ARRAYC:
case I_ARRAYI:
case I_ARRAYF:{ int i = 1;
for (; i < szof(*hp); i++) ptr[i] = hp[i];
ptr += i; break; }
case I_ARRAYP:{ int i = 1;
for (; i < hp[1] + 2; i++) ptr[i] = hp[i];
for (; i < szof(*hp); i++) ptr[i] = copy(hp[i], qtr, q);
ptr += i; break; }
default: { long *cp = ctab[idof(*hp)];
for (; *cp >= 0; cp++) ptr[*cp] = hp[*cp];
for (cp++; *cp >= 0; cp++) ptr[*cp] = copy(hp[*cp], qtr, q);
for (cp++; *cp >= 0; cp += 2) ptr[*cp] = hp[cp[1]] == T_POINTER
? copy(hp[*cp], qtr, q)
: hp[*cp];
ptr += szof(*hp); }
}
}
*qp = q;
return qtr;
}
u_long marshal(buf, ptr, sp, arity)
u_long *buf;
u_long *ptr;
u_long *sp;
u_long arity;
{
u_long *qtr = ptr + arity*2;
u_long *p = buf + MESGSZ;
u_long *q = buf + MESGSZ;
int i;
for (i = 0; i < arity; i++) {
u_long tag = ptr[i] = sp[arity + i];
u_long arg = ptr[arity + i] = sp[i];
if (tag == T_POINTER)
ptr[arity + i] = copy(arg, qtr, q);
}
qtr = traverse(ptr + arity*2, qtr, p, &q);
while (q < p) {
u_long *hp = (u_long *) *q++;
*hp = *(u_long *) *hp;
}
return (qtr - buf) * 4;
}
void umarshal(buf, ptr, sp, arity)
u_long *buf;
u_long *ptr;
u_long *sp;
u_long arity;
{
u_long *qtr = (u_long *) ((u_long) buf + buf[SIZE]);
u_long sz = arity*2*4 + (ptr - buf)*4;
u_long *hp = (u_long *) alloc(buf[SIZE] - sz);
u_long ho = (u_long) hp - buf[START] - sz;
int i;
for (i = 0; i < arity; i++)
sp[i] = ptr[i] == T_POINTER
? swizzle(ptr[arity + i], ho)
: ptr[arity + i];
ptr += arity * 2;
while (ptr < qtr) {
sz = szof(ptr);
hp[0] = ptr[0];
switch (idof(ptr)) {
case I_HANDLE: hp[1] = ptr[1];
hp[2] = ptr[2];
hp[3] = ptr[3]; break;
case I_LISTC:
case I_LISTI:
case I_LISTF: hp[1] = ptr[1];
hp[2] = swizzle(ptr[2], ho); break;
case I_LISTP: hp[1] = swizzle(ptr[1], ho);
hp[2] = swizzle(ptr[2], ho); break;
case I_ARRAYC:
case I_ARRAYI:
case I_ARRAYF: for (i = 1; i < sz; i++) hp[i] = ptr[i]; break;
case I_ARRAYP: for (i = 1; i < ptr[1] +2; i++) hp[i] = ptr[i];
for (; i < sz; i++) hp[i] = swizzle(ptr[i], ho); break;
default: { long *cp = ctab[idof(ptr)];
for (; *cp >= 0; cp++) hp[*cp] = ptr[*cp];
for (cp++; *cp >= 0; cp++) hp[*cp] = swizzle(ptr[*cp], ho);
for (cp++; *cp >= 0; cp += 2) hp[*cp] = ptr[cp[1]] == T_POINTER
? swizzle(ptr[*cp], ho)
: ptr[*cp]; }
}
hp += sz;
ptr += sz;
}
}
void mcret(handle)
u_long *handle;
{
u_long *buf;
u_long size;
u_long sp[2];
int mask;
int i = -1;
mask = sigblock(sigmask(SIGIO));
if (handle[2] != INADDR_ANY)
do if (++i == hno) {
error0("Internet address not in hosts list\n");
exit(-1);
}
while (handle[2] != htab[i].addr);
else {
i = pick(hno);
handle[2] = htab[i].addr;
}
sp[0] = (u_long) handle;
sp[1] = T_POINTER;
buf = (u_long *) malloc(MESGSZ * 4);
size = marshal(buf, buf + HEADSZ, sp, 1);
buf[SIZE] = htonl(size);
buf[ENDIAN] = 0xbeeffeed;
buf[START] = (u_long) buf;
buf[MTYPE] = MCRET;
buf[ADDR] = 0;
buf[PORT] = 0;
buf[XID] = 0;
buf[MID] = 0;
buf[INO] = 0;
buf[ONO] = 0;
handle[0] = H_HANDLE;
handle[3] = create(htab[i].addr, htab[i].port, handle[3], buf, size);
free(buf);
sigsetmask(mask);
}
void msend(handle, sp)
u_long *handle;
u_long *sp;
{
u_long *buf;
u_long *ptr;
u_long size;
int mask;
int i;
mask = sigblock(sigmask(SIGIO));
buf = (u_long *) malloc(MESGSZ * 4);
ptr = buf + HEADSZ;
for (i = 0; i < sp[2]; i++)
ptr[i] = sp[i + 3];
size = marshal(buf, ptr + sp[2], sp + 3 + sp[2], sp[1]);
buf[SIZE] = htonl(size);
buf[ENDIAN] = 0xbeeffeed;
buf[START] = (u_long) buf;
buf[MTYPE] = MSEND;
buf[ADDR] = root[2];
buf[PORT] = root[3];
buf[XID] = (u_long) ++qhead[1]->mp;
buf[MID] = sp[0];
buf[INO] = sp[1];
buf[ONO] = sp[2];
rpcno++;
*qhead[1]->mp = NUL;
tracer("sending request", size, buf);
transmit(handle[2], handle[3], buf, size);
tracer("...sent request", size, buf);
free(buf);
sigsetmask(mask);
}
u_long *mdone(hp)
u_long *hp;
{
u_long *sp = qhead[1]->sb - qhead[1]->ono;
u_long *buf;
u_long size;
int mask;
mask = sigblock(sigmask(SIGIO));
buf = (u_long *) malloc(MESGSZ * 4);
size = marshal(buf, buf + HEADSZ, sp, qhead[1]->ono);
buf[SIZE] = htonl(size);
buf[ENDIAN] = 0xbeeffeed;
buf[START] = (u_long) buf;
buf[MTYPE] = MDONE;
buf[ADDR] = qhead[1]->addr;
buf[PORT] = qhead[1]->port;
buf[XID] = (u_long) qhead[1]->xid;
buf[MID] = 0;
buf[INO] = 0;
buf[ONO] = qhead[1]->ono;
tracer("sending reply", size, buf);
transmit(qhead[1]->addr, qhead[1]->port, buf, size);
tracer("...sent reply", size, buf);
free(qhead[1]->stack);
free(buf);
tmove(1, 0);
space.hp = hp;
*space.hp = (u_long) twait(mask);
sigsetmask(mask);
return space.hp;
}
u_long *mquit(hp)
u_long *hp;
{
u_long *buf;
u_long size = HEADSZ * 4;
int mask;
mask = sigblock(sigmask(SIGIO));
buf = (u_long *) malloc(HEADSZ * 4);
buf[SIZE] = htonl(size);
buf[ENDIAN] = 0xbeeffeed;
buf[START] = (u_long) buf;
buf[MTYPE] = MQUIT;
buf[ADDR] = qhead[1]->addr;
buf[PORT] = qhead[1]->port;
buf[XID] = (u_long) qhead[1]->xid;
buf[MID] = 0;
buf[INO] = 0;
buf[ONO] = 0;
tracer("sending failure", size, buf);
transmit(qhead[1]->addr, qhead[1]->port, buf, size);
tracer("...sent failure", size, buf);
free(qhead[1]->stack);
free(buf);
tmove(1, 0);
space.hp = hp;
*space.hp = (u_long) twait(mask);
sigsetmask(mask);
return space.hp;
}
u_long *mrecv(hp, sp)
u_long *hp;
u_long *sp;
{
u_long *buf;
int mask;
mask = sigblock(sigmask(SIGIO));
while (!*qhead[1]->mp) {
print1("[pid %d] pending reply...\n", getpid());
sigpause(mask);
}
buf = (u_long *) *qhead[1]->mp--;
space.hp = hp;
if (buf[MTYPE] == MDONE)
umarshal(buf, buf + HEADSZ, sp, buf[ONO]);
*space.hp = buf[MTYPE];
free(buf);
sigsetmask(mask);
return space.hp;
}
void tinit()
{
u_long *buf = qhead[1]->mbuf;
u_long *ptr = buf + HEADSZ;
int mask;
int i;
mask = sigblock(sigmask(SIGIO));
qhead[1]->stack = (u_long *) malloc(STACKSZ * 4);
qhead[1]->mp = qhead[1]->stack - 1;
qhead[1]->sb = qhead[1]->stack + STACKSZ - buf[ONO];
qhead[1]->sp = qhead[1]->sb - max(buf[INO], buf[ONO]);
qhead[1]->pc = dtab[idof(root)][buf[MID]];
qhead[1]->hook = hook - TWO;
qhead[1]->mbuf = NUL;
qhead[1]->addr = buf[ADDR];
qhead[1]->port = buf[PORT];
qhead[1]->xid = buf[XID];
qhead[1]->ono = buf[ONO];
for (i = 0; i < buf[ONO]; i++)
qhead[1]->sb[i] = ptr[i];
umarshal(buf, ptr + buf[ONO], qhead[1]->sp, buf[INO]);
*--qhead[1]->sp = (u_long) root;
*--qhead[1]->sp = (u_long) (hook - TWO);
#if !defined(M68K) && !defined(I386)
qhead[1]->sp = qhead[1]->sb;
#endif !M68K && !I386
thno++;
free(buf);
sigsetmask(mask);
}
void tmove(u, v)
u_long u;
u_long v;
{
if (qtail[v])
qtail[v]->next = qhead[u];
else qhead[v] = qhead[u];
qtail[v] = qhead[u];
qhead[u] = qhead[u]->next;
qtail[v]->next = NUL;
if (!qhead[u]) qtail[u] = NUL;
}
Thread *twait(mask)
int mask;
{
while (!qhead[1]) {
print1("[pid %d] waiting...\n", getpid());
sigpause(mask);
}
if (qhead[1]->mbuf)
tinit();
return qhead[1];
}
u_long *cwait(n, v, hp, sp, pc)
u_long n;
u_long v;
u_long *hp;
u_long *sp;
u_long *pc;
{
int mask;
mask = sigblock(sigmask(SIGIO));
qhead[1]->sp = sp;
qhead[1]->pc = pc;
if (n == 0) {
qtail[1]->next = qhead[1];
qtail[1] = qhead[1];
qhead[1] = qhead[1]->next;
qtail[1]->next = NUL;
}
else {
qhead[1]->count = n;
tmove(1, v);
}
space.hp = hp;
*space.hp = (u_long) twait(mask);
sigsetmask(mask);
return space.hp;
}
void cpost(n, v)
u_long n;
u_long v;
{
Thread *rhead = NUL;
Thread *rtail = NUL;
Thread *vhead = NUL;
Thread *vtail = NUL;
Thread *vtemp = qhead[v];
int mask;
if (n == 0) n = TNO;
if (vtemp)
do if (n-- == 0) break;
else if (--vtemp->count == 0) {
if (rtail)
rtail->next = vtemp;
else rhead = vtemp;
rtail = vtemp;
}
else {
if (vtail)
vtail->next = vtemp;
else vhead = vtemp;
vtail = vtemp;
}
while (vtemp = vtemp->next);
mask = sigblock(sigmask(SIGIO));
if (qtail[1])
qtail[1]->next = rhead;
else qhead[1] = rhead;
if (rtail) {
qtail[1] = rtail;
qtail[1]->next = NUL;
}
qhead[v] = vhead ? vhead : vtemp;
if (vtail) vtail->next = vtemp;
if (!vtemp) qtail[v] = vtail;
sigsetmask(mask);
}
void zero(ptr, n)
u_long *ptr;
u_long n;
{
for (n = n / 4; n > 0;)
ptr[--n] = 0L;
}
char *alloc(n)
int n;
{
char *hp = (char *) space.hp;
space.hp = (u_long *) (hp + n);
return hp;
}
long iceil(x)
double x;
{
return ((long) ceil(x));
}
long ifloor(x)
double x;
{
return ((long) floor(x));
}
long iround(x)
double x;
{
return ((long) floor(x + 0.5));
}
long itrunca(x)
double x;
{
return ((long) (x > 0.0 ? floor(x) : ceil(x)));
}
double ffloat(x)
long x;
{
return ((double) x);
}
u_long *dbug()
{
fprintf(stderr, "I am in kernel dbug!\n");
}